#ifndef SYSTEMFONT_H
#define SYSTEMFONT_H

#include "hashtable.h"
#include "font.h"

// REVISIT: Need to finalize the conversion to C++ by renaming these and
//          placing them in the namespace.
#define SYSFONT_NORMAL		0				// Attrib...combine as needed
#define SYSFONT_BOLD		1
#define SYSFONT_ITALIC		2
#define SYSFONT_UNDERLINED	4

#define SYSFONT_MONOSPACED	"monospaced"	// Name (or use something else)
#define SYSFONT_SANSSERIF	"sansserif"

typedef struct _ABC ABC;

class PLIBEXP SystemFont : public Font
{
	public:
		struct ResourceShare;

	public:
		SystemFont(const String& name, int32 attrib, int32 ptSize, uint32 rgb);
		SystemFont(const String& name);
		~SystemFont();

		static const String& fontName(const char *fontalias);

		static	void	setFontName(const String& langcode);
		static	void	setFontCharSet(uint8 charSet);
        static  uint8   getFontCharSet();

		// Font interface
		//
		virtual bool8	isLoaded();

		virtual int32	ascent();

		virtual int32	charOffset(const uint16 ch);

		virtual int32	descent();

		virtual void	drawText(int32 * x, int32 y, const uint16* text, uint32 len, pCFrame frame);
		virtual void	drawText(int32 * x, int32 y, const uint16* text, pCFrame frame);
		virtual void	drawText(int32 * x, int32 y, const uint16 ch, pCFrame frame);

		virtual void	drawText(int32 * x, int32 y, const uint16* text, uint32 len, pCBitmap bitmap);
		virtual void	drawText(int32 * x, int32 y, const uint16* text, pCBitmap bitmap);
		virtual void	drawText(int32 * x, int32 y, const uint16 ch, pCBitmap bitmap);

		virtual int32	externalLeading();

		virtual void	glyphMetric(int32 * width, int32 * height,
							int32 * left, int32 * right, int32 * top,
							int32 * bottom, const uint16 ch);
		virtual void	glyphMetric(int32 * width, int32 * height,
							int32 * left, int32 * right, int32 * top,
							int32 * bottom, const uint16* text, uint32 len);
		
		virtual void	glyphMetric(int32 * width, int32 * height,
							int32 * left, int32 * right, int32 * top,
							int32 * bottom, const uint16* text);

		virtual bool8	isA(uint32 type);

		virtual uint32	kind();

		virtual int32	maximumGlyphHeight();
		virtual int32	maximumGlyphWidth();

		virtual int32	maximumTextHeight();
		virtual int32	maximumTextWidth();

		virtual void	textMetric(int32 * width, int32 * height, int32 * abcA,
							int32 * abcC, const uint16 ch);
		
		virtual void	textMetric(int32 * width, int32 * height, int32 * abcA,
							int32 * abcC, const uint16* text);

		virtual void	textMetric(int32 * width, int32 * height, int32 * abcA,
							int32 * abcC, const uint16* text, uint32 len);

		// Common interface
		//
		void	drawText(pCFrame frame, int32 * x, int32 y, const uint16* text, uint32 len);
		void	drawText(pCFrame frame, int32 * x, int32 y, const char* text, uint32 len);
		void	drawText(pCFrame frame, int32 * x, int32 y, const uint16* text);
		void	drawText(pCFrame frame, int32 * x, int32 y, const char* text);
		
		void	textMetrics(const uint16* text, uint32 len, int32 * width, int32 * height);
		void	textMetrics(const char* text, uint32 len, int32 * width, int32 * height);

		void	textMetrics(const uint16* text, int32 * width, int32 * height);
		void	textMetrics(const char* text, int32 * width, int32 * height);

		void	textMetrics(const uint16 ch, int32 * width, int32 * height);

		// Platform interface
		//

	protected:
		static HashTable<ResourceShare*>* sStash;

	protected:
		HANDLE		mFont;
		uint32		mColor;
		pCFrame		*mBitmapFrame;
		TEXTMETRIC	mMetric;

        bool8       mTrueType;

		// Every SystemFont of the same resource shares the same pointer.
		ResourceShare*	mResourceShare;
		static String	mFontName;
		static uint8	mFontCharSet;

        int32 getTextWidth( HDC hdc, const uint16* text, uint32 len );

	// prohibited
	private:
		SystemFont();
		SystemFont(SystemFont &);
		SystemFont & operator=(SystemFont &);
};

struct SystemFont::ResourceShare
{
	HANDLE		mFont;
	uint32		mColor;
	pCFrame		*mBitmapFrame;
	TEXTMETRIC	mMetric;
	uint32		refcount;
};

#define newCSystemFont(name, attrib, ptSize, rgb)	new SystemFont(name, attrib, ptSize, rgb)
#define CFontDrawText(t, f, X, Y, text)				(##t)->drawText(##f, ##X, ##Y, ##text)
#define deleteVObj(o)								delete (##o)
#define CFontTextMetrics(t, text, pWid, pHei)		(##t)->textMetrics(##text, ##pWid, ##pHei)

#endif
